package com.example.openim.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.CharArrayBuffer;
import org.apache.http.util.EntityUtils;
import org.springframework.http.MediaType;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;

/**
 * @description:
 * @author: zyc
 * @created: 2024-06-26 13:49
 */
@Slf4j
public class HttpsUtil {

    /**
     * get请求
     *
     * @param httpUrl
     * @return
     */
    public static String doGet(String httpUrl) {
        CloseableHttpClient httpClient = wrapClient();
        CloseableHttpResponse response = null;
        HttpGet get = new HttpGet(httpUrl);
        String result = null;
        try {
            response = httpClient.execute(get);
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }
        } catch (ClientProtocolException e) {
            // T0D0 Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // T0D0 Auto-generated catch block
            // e.printStackTrace();
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * post请求
     *
     * @param url
     * @param paramMap
     * @param headerMap
     * @param bodyJson
     * @return
     * @throws IOException
     */
    public static String sendPostMap(String url, Map<String, String> paramMap, Map<String,String> headerMap, String bodyJson) throws IOException {
        String result = null;
        CloseableHttpClient httpclient = wrapClient();
        HttpPost post = new HttpPost(url);

        StringEntity stringEntity = new StringEntity(bodyJson, "UTF-8");
        stringEntity.setContentEncoding("UTF-8");
        stringEntity.setContentType("application/json");
        post.setEntity(stringEntity);

        if (paramMap != null) {
            paramMap = new HashMap<>();
            List<NameValuePair> formparams = setHttpParams(paramMap);
            UrlEncodedFormEntity param = new UrlEncodedFormEntity(formparams, "UTF-8");
            //通过setEntity()设置参数给post
            post.setEntity(param);
        }
        // 设置请求头
        setHeaderMap(post, headerMap);

        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(post);
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }
            return result;
        } catch (UnsupportedEncodingException e) {
            log.error("unsupportedEncodingException:" + e.getMessage(), e);
        } catch (ClientProtocolException e) {
            log.error("clientProtocolException:" + e.getMessage(), e);
        } catch (IOException e) {
            log.error("I0Exception:" + e.getMessage(), e);
        } finally {
            try {
                httpclient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                log.error("I0Exception2:" + e.getMessage(), e);
            }
        }
        return null;
    }

    /**
     * post请求-绿舟
     *
     * @param url
     * @param paramMap
     * @param headerMap
     * @param bodyJson
     * @return
     * @throws IOException
     */
    public static String sendPostMapLz(String url, Map<String, String> paramMap, Map<String,String> headerMap, String bodyJson) throws IOException {
        String result = null;
        CloseableHttpClient httpclient = wrapClient();
        HttpPost post = new HttpPost(url);

        StringEntity stringEntity = new StringEntity(bodyJson, "UTF-8");
        stringEntity.setContentType("application/json");
        post.setEntity(stringEntity);

        if (paramMap != null) {
            paramMap = new HashMap<>();
            List<NameValuePair> formparams = setHttpParams(paramMap);
            UrlEncodedFormEntity param = new UrlEncodedFormEntity(formparams, "UTF-8");
            //通过setEntity()设置参数给post
            post.setEntity(param);
        }
        // 设置请求头
        setHeaderMap(post, headerMap);

        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(post);
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }
            return result;
        } catch (UnsupportedEncodingException e) {
            log.error("unsupportedEncodingException:" + e.getMessage(), e);
        } catch (ClientProtocolException e) {
            log.error("clientProtocolException:" + e.getMessage(), e);
        } catch (IOException e) {
            log.error("I0Exception:" + e.getMessage(), e);
        } finally {
            try {
                httpclient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                log.error("I0Exception2:" + e.getMessage(), e);
            }
        }
        return null;
    }

    /**
     * post请求-绿舟角标推送相关接口
     *
     * @param url
     * @param paramMap
     * @param headerMap
     * @param bodyJson
     * @return
     * @throws IOException
     */
    public static String sendPostMapLzSub(String url, Map<String, Object> paramMap, Map<String,String> headerMap, String bodyJson, String date, String sign) throws IOException {
        String result = null;
        CloseableHttpClient httpclient = wrapClient();
        HttpPost post = new HttpPost(url);

//        StringEntity stringEntity = new StringEntity(bodyJson, "UTF-8");
//        stringEntity.setContentType("application/x-www-form-urlencoded");
//        post.setEntity(stringEntity);

        if (paramMap != null) {
            paramMap = new HashMap<>();
            List<NameValuePair> formparams = setHttpParamsLz(paramMap);
            UrlEncodedFormEntity param = new UrlEncodedFormEntity(formparams, "UTF-8");
            //通过setEntity()设置参数给post
            post.setEntity(param);
        }
        // 设置请求头
//        setHeaderMap(post, headerMap);
        post.setHeader("Content-Type", MediaType.APPLICATION_FORM_URLENCODED.toString());
        post.setHeader("Wps-Docs-Date", date);
        post.setHeader("Wps-Docs-Authorization", sign);

        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(post);
            log.info("response============>" + response);
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }
            return result;
        } catch (UnsupportedEncodingException e) {
            log.error("unsupportedEncodingException:" + e.getMessage(), e);
        } catch (ClientProtocolException e) {
            log.error("clientProtocolException:" + e.getMessage(), e);
        } catch (IOException e) {
            log.error("I0Exception:" + e.getMessage(), e);
        } finally {
            try {
                httpclient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                log.error("I0Exception2:" + e.getMessage(), e);
            }
        }
        return null;
    }

    /**
     * put请求
     *
     * @param url
     * @param paramMap
     * @param headerMap
     * @param bodyJson
     * @return
     * @throws IOException
     */
    public static String sendPutMap(String url, Map<String, String> paramMap, Map<String,String> headerMap, String bodyJson) throws IOException {
        String result = null;
        CloseableHttpClient httpclient = wrapClient();
        HttpPut put = new HttpPut(url);

        StringEntity stringEntity = new StringEntity(bodyJson, "UTF-8");
        stringEntity.setContentEncoding("UTF-8");
        stringEntity.setContentType("application/json");
        put.setEntity(stringEntity);

        if (paramMap != null) {
            paramMap = new HashMap<>();
            List<NameValuePair> formparams = setHttpParams(paramMap);
            UrlEncodedFormEntity param = new UrlEncodedFormEntity(formparams, "UTF-8");
            //通过setEntity()设置参数给post
            put.setEntity(param);
        }
        // 设置请求头
        setHeaderMap(put, headerMap);

        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(put);
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }
            return result;
        } catch (UnsupportedEncodingException e) {
            log.error("unsupportedEncodingException:" + e.getMessage(), e);
        } catch (ClientProtocolException e) {
            log.error("clientProtocolException:" + e.getMessage(), e);
        } catch (IOException e) {
            log.error("I0Exception:" + e.getMessage(), e);
        } finally {
            try {
                httpclient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                log.error("I0Exception2:" + e.getMessage(), e);
            }
        }
        return null;
    }

    /**
     * Delete请求
     *
     * @param url
     * @param paramMap
     * @param headerMap
     * @param bodyJson
     * @return
     * @throws IOException
     */
    public static String sendDeleteMap(String url, Map<String, String> paramMap, Map<String,String> headerMap, String bodyJson) throws IOException {
        String result = null;
        CloseableHttpClient httpclient = wrapClient();
        HttpDelete delete = new HttpDelete(url);

        StringEntity stringEntity = new StringEntity(bodyJson, "UTF-8");
        stringEntity.setContentEncoding("UTF-8");
        stringEntity.setContentType("application/json");
//        delete.setEntity(stringEntity);

        if (paramMap != null) {
            paramMap = new HashMap<>();
            List<NameValuePair> formparams = setHttpParams(paramMap);
            UrlEncodedFormEntity param = new UrlEncodedFormEntity(formparams, "UTF-8");
            //通过setEntity()设置参数给post
//            delete.setEntity(param);
        }
        // 设置请求头
        setHeaderMap(delete, headerMap);

        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(delete);
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = entityToString(entity);
            }
            return result;
        } catch (UnsupportedEncodingException e) {
            log.error("unsupportedEncodingException:" + e.getMessage(), e);
        } catch (ClientProtocolException e) {
            log.error("clientProtocolException:" + e.getMessage(), e);
        } catch (IOException e) {
            log.error("I0Exception:" + e.getMessage(), e);
        } finally {
            try {
                httpclient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                log.error("I0Exception2:" + e.getMessage(), e);
            }
        }
        return null;
    }

    private static String entityToString(HttpEntity entity) throws IOException {
        String result = null;
        if (entity != null) {
            long lenth = entity.getContentLength();
            if (lenth != -1 && lenth < 2048) {
                result = EntityUtils.toString(entity, "UTF-8");
            } else {
                InputStreamReader reader1 = null;
                try {
                    reader1 = new InputStreamReader(entity.getContent(), "UTF-8");
                    CharArrayBuffer buffer = new CharArrayBuffer(2048);
                    char[] tmp = new char[1024];
                    int l;
                    while ((l = reader1.read(tmp)) != -1) {
                        buffer.append(tmp, 0, l);
                    }
                    result = buffer.toString();
                } finally {
                    if (reader1 != null) {
                        reader1.close();
                    }
                }
            }
        }
        return result;
    }

    private static CloseableHttpClient wrapClient() {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };
            ctx.init(null, new TrustManager[]{tm}, null);
            SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
            return HttpClients.custom().setSSLSocketFactory(ssf).build();
        } catch (Exception e) {
            return HttpClients.createDefault();
        }
    }

    private static void setHeaderMap(HttpRequestBase httpRequestBase, Map<String,String> headerMap){
        if(headerMap != null) {
            for(Map.Entry<String, String> entPM:headerMap.entrySet()) {
                String key = entPM.getKey();
                String val = entPM.getValue();
                httpRequestBase.setHeader(key,val);
            }
        }
    }

    private static List<NameValuePair> setHttpParams(Map<String, String> paramMap) {
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        Set<Map.Entry<String, String>> set = paramMap.entrySet();
        for (Map.Entry<String, String> entry : set) {
            formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        return formparams;
    }

    private static List<NameValuePair> setHttpParamsLz(Map<String, Object> paramMap) {
        List<NameValuePair> formparams = new ArrayList<>();
        for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
            formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
        }
        return formparams;
    }

}
